<template>
  <div class="container">
    <split-pane v-on:resize="resize" :min-percent='10' :default-percent='80' split="vertical" style="border-left: 6px solid #dce3e8;width: 100%;height: 100%;position: absolute;left: 0;top: 0;">
      <template slot="paneL">
        <div class="btn_group e-flex">
          <div class="left e-flex">
            <el-button class="btn" type="primary" size="small">导入</el-button>
            <el-button class="btn" type="primary" size="small">导出</el-button>
          </div>
          <div class="right e-flex">
            <el-button class="btn" type="primary" size="small" @click="addLane">添加泳道</el-button>
            <el-button class="btn" type="primary" size="small" @click="onSubmit">保存</el-button>
          </div>
        </div>
        <div id="wrap">
          <div class="contextMenu" v-if="showMenu" :style="{'left':screenX+'px','top':screenY+'px'}" @contextmenu.prevent="preventContextMenu" @mouseleave="leave()">
            <div class="option line" @click="moveLeft">左移</div>
            <div class="option" @click="moveRight">右移</div>
          </div>
          <div id="chart-wrap">
            <div id="chart-diagram"></div>
          </div>
        </div>
      </template>
      <template slot="paneR">
        <split-pane class="split_pane" :min-percent='0' :default-percent='40' split="horizontal">
          <template slot="paneL">
            <div class="title">组件</div>
            <div class="collapse">
              <el-collapse v-model="activeNames">
                <template v-for="(item,index) in componentList">
                  <el-collapse-item :title="item.title" :name="index">
                    <div class="chart-palette-box"  style="height: 300px;">
                      <div class="chart-palettes" :id="item.id"></div>
                    </div>
                  </el-collapse-item>
                </template>
                <!--<el-collapse-item title="硬件操作" name="1" v-for="(item,index) in componentList">
                  <div class="chart-palette-box"  style="height: 300px;">
                    <div class="chart-palettes" id="chart-palette"></div>
                  </div>
                </el-collapse-item>
                <el-collapse-item title="通讯处理" name="2">
                  <div class="chart-palette-box"  style="height: 300px;">
                    <div class="chart-palettes" id="chart-palette2"></div>
                  </div>
                </el-collapse-item>
                <el-collapse-item title="PBOC流程" name="3">
                  <div>暂无数据</div>
                </el-collapse-item>
                <el-collapse-item title="页面展示" name="4">
                  <div>暂无数据</div>
                </el-collapse-item>
                <el-collapse-item title="流程跳转" name="5">
                  <div>暂无数据</div>
                </el-collapse-item>
                <el-collapse-item title="业务组件" name="6">
                  <div>暂无数据</div>
                </el-collapse-item>
                <el-collapse-item title="业务组件" name="6">
                  <div>暂无数据</div>
                </el-collapse-item>-->
              </el-collapse>
            </div>
          </template>
          <template slot="paneR">
            <div class="title" title="hello">属性区</div>
            <template v-for="(value,key,i) in properties">
              <component :is="value.component" :ui="ui" :properties="value" :keys="key" @changeAttr="changeAttr"></component>
            </template>

            <!--<component is="eSelect"></component>
            <component is="eRadio" :options="[{'value':0, name:'设备1'},{'value':1, name:'设备2'}]"></component>
            <component is="eNumber"></component>
            <component is="eAutocomplete"></component>-->
          </template>
        </split-pane>
      </template>
    </split-pane>
    <!--<button @click="onSubmit">保存</button>
    <div id="wrap">
      <div id="chart-wrap">
        <div id="chart-palette"></div>
        <div id="chart-diagram"></div>
      </div>
    </div>-->
  </div>
</template>

<script>
  import componentList from "../assets/config/component/componentList"
  import dataTest from "../assets/config/attribute/test"
  /*表单组件*/
  import eText from "./formComponent/e-text"
  import eInput from "./formComponent/e-input"
  import eNumber from "./formComponent/e-number"
  import eRadio from "./formComponent/e-radio"
  import eSelect from "./formComponent/e-select"
  import eAutocomplete from "./formComponent/e-autocomplete"
  //import go from "../assets/js/go"
  import "@/assets/js/go.js";
  import splitPane from 'vue-splitpane';
  //import go from "gojs"
  const MAKE = go.GraphObject.make; //创建一个GoJS对象
  export default {
      components:{
          splitPane,
          eText,
          eInput,
          eNumber,
          eRadio,
          eSelect,
          eAutocomplete
      },
    props:{
      flowChart:{
        type: Object,
      }
    },
    data() {
      return {
          activeNames: [],
          activeNode:{},
          screenX: '',
          screenY: '',
          showMenu:false,
          selectedLane:'', //当前选中的泳道key,用于泳道间位置移动
          componentList:'',
          properties:{},
          ui:{}
      }
    },
    mounted() {
          console.log(dataTest)
        this.properties = dataTest.properties;
          this.ui = dataTest.ui;
          this.componentList = componentList;
      function PoolLayout() {
        go.GridLayout.call(this);
        this.MINLENGTH = 200; // this controls the minimum length of any swimlane
        this.MINBREADTH = 100; // this controls the minimum breadth of any non-collapsed swimlane
        this.cellSize = new go.Size(0, 0);
        this.wrappingColumn = Infinity;
        this.wrappingWidth = Infinity;
        this.spacing = new go.Size(50, 50);
        this.alignment = go.GridLayout.Position;
      }

      go.Diagram.inherit(PoolLayout, go.GridLayout);

      PoolLayout.prototype.doLayout = function (coll) {
        var diagram = this.diagram;
        if (diagram === null) return;
        diagram.startTransaction("PoolLayout");
        // make sure all of the Group Shapes are big enough
        var minlen = this.computeMinPoolLength();
        var lay = this;
        diagram.findTopLevelGroups().each(function (lane) {
          if (!(lane instanceof go.Group)) return;
          var shape = lane.selectionObject;
          if (shape !== null) { // change the desiredSize to be big enough in both directions
            var sz = lay.computeLaneSize(lane);
            //shape.width = (!isNaN(shape.width)) ? Math.max(shape.width, sz.width) : sz.width;
            shape.width = 150;
            // if you want the height of all of the lanes to shrink as the maximum needed height decreases:
            shape.height = minlen;
            // if you want the height of all of the lanes to remain at the maximum height ever needed:
            //shape.height = (isNaN(shape.height) ? minlen : Math.max(shape.height, minlen));
            var cell = lane.resizeCellSize;
            if (!isNaN(shape.width) && !isNaN(cell.width) && cell.width > 0) shape.width = Math.ceil(shape.width / cell.width) *
              cell.width;
            if (!isNaN(shape.height) && !isNaN(cell.height) && cell.height > 0) shape.height = Math.ceil(shape.height /
              cell.height) * cell.height;
          }
        });
        // now do all of the usual stuff, according to whatever properties have been set on this GridLayout
        go.GridLayout.prototype.doLayout.call(this, coll);
        diagram.commitTransaction("PoolLayout");
      };

      // compute the minimum length of the whole diagram needed to hold all of the Lane Groups
      PoolLayout.prototype.computeMinPoolLength = function () {
        var len = this.MINLENGTH;
        mySelf.myDiagram.findTopLevelGroups().each(function (lane) {
          var holder = lane.placeholder;
          if (holder !== null) {
            var sz = holder.actualBounds;
            len = Math.max(len, sz.height);
          }
        });
        return len;
      }

      // compute the minimum size for a particular Lane Group
      PoolLayout.prototype.computeLaneSize = function (lane) {
        // assert(lane instanceof go.Group);
        var sz = new go.Size(lane.isSubGraphExpanded ? this.MINBREADTH : 1, this.MINLENGTH);
        if (lane.isSubGraphExpanded) {
          var holder = lane.placeholder;
          if (holder !== null) {
            var hsz = holder.actualBounds;
            sz.width = Math.max(sz.width, hsz.width);
          }
        }
        // minimum breadth needs to be big enough to hold the header
        var hdr = lane.findObject("HEADER");
        if (hdr !== null) sz.width = Math.max(sz.width, hdr.actualBounds.width);
        return 100;
        //return sz;
      }


      var mySelf = this;
      mySelf.myDiagram = MAKE(go.Diagram, "chart-diagram", {  //chart-diagram同HTML中画布DIV的id一致
        //initialContentAlignment: go.Spot.Center, // 居中显示
       // contentAlignment: go.Spot.TopLeft,
        allowDelete: true, //是否允许删除
        allowCopy: true,  //是否允许复制
        allowClipboard: true,  //是否允许粘贴
        allowDrop: true, // must be true to accept drops from the Palette
        allowMove: true, //允许拖动
        "grid.visible": true, //显示网格
        // use a simple layout to stack the top-level Groups next to each other
        layout: MAKE(PoolLayout),  //无泳道的情况下无需设置此样式
        // disallow nodes to be dragged to the diagram's background
        mouseDrop: function (e) {
          e.diagram.currentTool.doCancel();   //无泳道的情况下取消拖拽限制
        },
        // a clipboard copied node is pasted into the original node's group (i.e. lane).
        "commandHandler.copiesGroupKey": true,
        // automatically re-layout the swim lanes after dragging the selection
        "SelectionMoved": relayoutDiagram, // this DiagramEvent listener is
        "SelectionCopied": relayoutDiagram, // defined above
        "undoManager.isEnabled": true,
        // allow TextEditingTool to start without sefindTopLevelGroupslecting first
        //"textEditingTool.starting": go.TextEditingTool.SingleClick,
        "toolManager.mouseWheelBehavior": go.ToolManager.WheelZoom, //有鼠标滚轮事件放大和缩小，而不是向上和向下滚动
      }); //构建gojs对象
      function relayoutDiagram() {
        mySelf.myDiagram.selection.each(function (n) {
          n.invalidateLayout();
        });
        mySelf.myDiagram.layoutDiagram();
      }

      mySelf.myDiagram.addDiagramListener("ObjectSingleClicked", function (e) {
        //监听元素点击事件

          mySelf.activeNode = e.subject.part.data;
          mySelf.$bus.$emit('activeNode',mySelf.activeNode);
          //console.log(mySelf.activeNode);
        //console.log(e.subject.part);
         // e.subject.part.data.text = 'abby';

          /*var node = mySelf.myDiagram.model.findNodeDataForKey(e.subject.part.data.key);
          mySelf.myDiagram.model.setDataProperty( node, 'lable', "恒银");
          console.log(e.subject.part.data)*/
          //console.log(mySelf.myDiagram.model)
          //mySelf.myDiagram.model.updateTargetBindings(e);

      });
      mySelf.myDiagram.addModelChangedListener(function(evt) {
        //if (evt.isTransactionFinished) console.log(evt.model);
      });
      mySelf.myDiagram.addDiagramListener("BackgroundSingleClicked", function (e) {
        //监听背景点击事件
        console.log("Double-clicked at" + e.diagram.lastInput.documentPoint);
      });
      mySelf.myDiagram.addDiagramListener("externalobjectsdropped", function (e) {
        e.subject.each(function (n) {
//得到从Palette拖过来的节点
          /*console.log(n)
          console.log(n.data.key);*/
        });
      });

        /*mySelf.myDiagram.addDiagramListener("ObjectContextClicked", function (e) {
            //监听粘贴事件
            console.log( e);
        });*/
      mySelf.myDiagram.addDiagramListener("ClipboardPasted", function (e) {
        //监听粘贴事件
        console.log("Pasted" + e.diagram.selection.count + "parts");
      });


      mySelf.myDiagram.linkTemplate = MAKE(go.Link, {
          routing: go.Link.AvoidsNodes,  //设置连接线的绕行路线
          curve: go.Link.JumpGap, //JumpOver:连线弧形交叉；JumpGap：连线不交叉
          corner: 5,
          toShortLength: 4,
          relinkableFrom: true,
          relinkableTo: true,
          reshapable: true,
          resegmentable: true,
          // mouse-overs subtly highlight links:
          /*mouseEnter: function(e, link) {
            link.findObject("HIGHLIGHT").stroke = "rgba(30,144,255,0.2)";
          },
          mouseLeave: function(e, link) {
            //link.findObject("HIGHLIGHT").stroke = "transparent";
          }*/
        },
        new go.Binding("points").makeTwoWay(),
        MAKE(go.Shape, {
          strokeWidth: 2,
          stroke: "#F60"
        }),
        MAKE(go.Shape, {
          toArrow: "Standard",
          fill: "red",
          stroke: "blue"
        }), //箭头
        MAKE(go.TextBlock, {
            margin: 20,
            stroke: "#000000",
            font: "14px sans-serif",
            width: 50,
                editable: false,
            wrap: go.TextBlock.WrapDesiredSize
          },
          new go.Binding("text", "linktext")), {
          toolTip: MAKE(go.Adornment, "Auto",
            MAKE(go.Shape, {
              fill: "transparent",
              stroke: "transparent"
            }),
            MAKE(go.TextBlock, {
                editable: false,
              margin: 4
            }, new go.Binding("text", "name1"))
          ) // end of Adornment
        }
      );
      mySelf.myDiagram.toolManager.linkingTool.temporaryLink.routing = go.Link.Orthogonal; //设置拖出的连线可自动计算线的样式
      mySelf.myDiagram.toolManager.relinkingTool.temporaryLink.routing = go.Link.Orthogonal; //连接前：设置拖出的连线可自动计算线的样式
      let myModel = MAKE(go.GraphLinksModel); //也可以创建link model;需要配置myModel.linkDataArray 如下
      /*function sameColor(fromnode, fromport, tonode, toport) {
        console.log(fromnode, fromport, tonode, toport)
        return fromnode.data.color !== tonode.data.color;
      }
      mySelf.myDiagram.toolManager.linkingTool.linkValidation = sameColor;
      mySelf.myDiagram.toolManager.relinkingTool.linkValidation = sameColor;*/
      if(JSON.stringify(this.flowChart)!=='{}'){
        myModel = this.flowChart;
        // myModel.Dc = this.flowChart.Dc;
        // myModel.Pc = this.flowChart.Pc;
      }else {
        myModel.nodeDataArray = [
          {"key": 3, "isGroup": true, "text": "Group A"},
          {"key": 4, "isGroup": true, "text": "Group B"},
          {"key": 5, "isGroup": true, "text": "Group C"},
          {"key": 6, "isGroup": true, "text": "Group D"},
          {"key": 7, "isGroup": true, "text": "Group E"},
          {"text": "first A", "group": 3, "key": -7},
          {"text": "second A", "group": 3, "key": -8},
          {"text": "first B", "group": 4, "key": -9},
          {"text": "second B", "group": 4, "key": -10},
          {"text": "third B", "group": 4, "key": -11},
          {"text": "first C", "group": 5, "key": -12,"age":12},
          {"text": "second C", "group": 5, "key": -13},
          {"text": "first D", "group": 6, "key": -14},
          {"text": "first E", "group": 7, "key": -15}
        ];
        myModel.linkDataArray = [
          {"from":3, "to":4, "fromPort":"R", "toPort":"L"},
          {"from":4, "to":5, "fromPort":"R", "toPort":"L"},
          {"from":5, "to":6, "fromPort":"R", "toPort":"L"},
          {"from":6, "to":7, "fromPort":"R", "toPort":"L"}
            //{"from":3, "to":4, "fromPort":"R", "toPort":"L","linktext": "default"}
        ];
      }
      var lightText = "whitesmoke";
      mySelf.myDiagram.groupTemplate =
        MAKE(go.Group, "Vertical",
          {
            //selectable: true,
            selectionObjectName: "SHAPE", // even though its not selectable, this is used in the layout
            layerName: "Background", // all lanes are always behind all nodes and links
            layout: MAKE(go.GridLayout, // automatically lay out the lane's subgraph
              {
                wrappingColumn: 1,
                cellSize: new go.Size(1, 1),
                spacing: new go.Size(25, 25),
                //alignment: go.GridLayout.Position,  //不设置组内元素居中显示
                comparer: function(a, b) { // can re-order tasks within a lane
                  var ay = a.location.y;
                  var by = b.location.y;
                  if (isNaN(ay) || isNaN(by)) return 0;
                  if (ay < by) return -1;
                  if (ay > by) return 1;
                  return 0;
                }
              }),
            click: function(e, grp) { // allow simple click on group to clear selection
              console.log('asdas')
              //if (!e.shift && !e.control && !e.meta) e.diagram.clearSelection();
            },
            computesBoundsAfterDrag: true, // needed to prevent recomputing Group.placeholder bounds too soon
            handlesDragDropForMembers: true, // don't need to define handlers on member Nodes and Links
            mouseDragEnter: function(e, grp, prev) {
              //highlightGroup(grp, true);
            },
            mouseDragLeave: function(e, grp, next) {
              highlightGroup(grp, false);
            },
            mouseDrop: function(e, grp) { // dropping a copy of some Nodes and Links onto this Group adds them to this Group
              // don't allow drag-and-dropping a mix of regular Nodes and Groups
                console.log('ok')
              if (e.diagram.selection.all(function(n) {
                return !(n instanceof go.Group);
              })) {
                var ok = grp.addMembers(grp.diagram.selection, true);
                if (!ok) grp.diagram.currentTool.doCancel();
              }
            },
              contextClick(e,grp){
                mySelf.showMenu = true;
                mySelf.screenX = e.event.offsetX
                  mySelf.screenY = e.event.offsetY;
                  mySelf.selectedLane = grp.data.key;
                //console.log( mySelf.selectedLane);
                //console.log( mySelf.screenX, mySelf.screenY)
              },
            subGraphExpandedChanged: function(grp) {  //泳道伸缩功能
              var shp = grp.selectionObject;
              if (grp.diagram.undoManager.isUndoingRedoing) return;
              if (grp.isSubGraphExpanded) {
                shp.width = grp._savedBreadth;
              } else { // remember the original width
                grp._savedBreadth = shp.width;
                shp.width = NaN;
              }
            }
          },
          new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify),
          new go.Binding("isSubGraphExpanded", "expanded").makeTwoWay(),
          MAKE(go.Panel, "Horizontal", {
              name: "HEADER",
              alignment: go.Spot.Left,
              background:"#FFDD33",
              stretch: go.GraphObject.Horizontal,
              padding: 8,
            },
            /*MAKE("SubGraphExpanderButton", {
              margin: 5
            }),*/ // this remains always visible
            MAKE(go.TextBlock, // the lane label
              {
                font: "15px Lato, sans-serif",
                editable: false,
                margin: new go.Margin(2, 0, 0, 0),
              },
              // this is hidden when the swimlane is collapsed
              new go.Binding("visible", "isSubGraphExpanded").ofObject(),
              new go.Binding("text").makeTwoWay()),
          ), // end Horizontal Panel
          MAKE(go.Panel, "Auto", // the lane consisting of a background Shape and a Placeholder representing the subgraph
            MAKE(go.Shape, "Rectangle", // this is the resized object
              {
                name: "SHAPE",
                fill: "#F1F1F1",
                stroke: "#FFDD33",
                strokeWidth: 4,
              }, // strokeWidth controls space between lanes
              new go.Binding("fill", "isHighlighted", function(h) {
                return h ? "#FFDD33" : "transparent";
              }).ofObject(),
              new go.Binding("desiredSize", "size", go.Size.parse).makeTwoWay(go.Size.stringify)),
            MAKE(go.Placeholder, {
              padding: 12,
              alignment: go.Spot.TopLeft
            }),
            MAKE(go.TextBlock, // this TextBlock is only seen when the swimlane is collapsed
              {
                name: "LABEL",
                font: "15px Lato, sans-serif",
                editable: false,
                angle: 90,
                alignment: go.Spot.TopLeft,
                margin: new go.Margin(4, 0, 0, 2)
              },
              new go.Binding("visible", "isSubGraphExpanded", function(e) {
                return !e;
              }).ofObject(),
              new go.Binding("text").makeTwoWay())
          )
        );

      function highlightGroup(e, grp, show) {
        if (!grp || grp.constructor != Object) return;
        e.handled = true;
        if (show) {
          // cannot depend on the grp.diagram.selection in the case of external drag-and-drops;
          // instead depend on the DraggingTool.draggedParts or .copiedParts
          var tool = grp.diagram.toolManager.draggingTool;
          var map = tool.draggedParts || tool.copiedParts;  // this is a Map
          // now we can check to see if the Group will accept membership of the dragged Parts
          if (grp.canAddMembers(map.toKeySet())) {
            grp.isHighlighted = true;
            return;
          }
        }
        grp.isHighlighted = false;
      }

      function finishDrop(e, grp) {
        console.log(grp.diagram.selection)
        var ok = (grp !== null
          ? grp.addMembers(grp.diagram.selection, true)
          : e.diagram.commandHandler.addTopLevelParts(e.diagram.selection, true));
        if (!ok) e.diagram.currentTool.doCancel();
      }

      function makeLayout(horiz) {  // a Binding conversion function
        if (horiz) {
          return MAKE(go.GridLayout,
            {
              wrappingWidth: Infinity, alignment: go.GridLayout.Position,
              cellSize: new go.Size(1, 1), spacing: new go.Size(4, 4)
            });
        } else {
          return MAKE(go.GridLayout,
            {
              wrappingColumn: 1, alignment: go.GridLayout.Position,
              cellSize: new go.Size(1, 1), spacing: new go.Size(4, 4)
            });
        }
      }

      function defaultColor(horiz) {  // a Binding conversion function
        return horiz ? "#FFDD33" : "#33D3E5";
      }

      function defaultFont(horiz) {  // a Binding conversion function
        return horiz ? "bold 18px sans-serif" : "bold 16px sans-serif";
      }

      mySelf.myDiagram.nodeTemplate =
        MAKE(go.Node, "Horizontal",
          {selectionChanged: nodeSelectionChanged},
//节点选中改变事件，nodeSelectionChanged为回调的方法名
          MAKE(go.Panel, "Auto",
            MAKE(go.Shape,//节点形状和背景颜色的设置
              {fill: "#1F4963", stroke: null}
            ),
            MAKE(go.TextBlock,
              {
                  editable: false
              },
              new go.Binding("text", "key")),
          ),
        );

      function nodeSelectionChanged(node) {
        console.log(node)
      }

      mySelf.myDiagram.nodeTemplateMap.add(
        "",
        MAKE(
          go.Node,
          "Spot",
          nodeStyle(),
          MAKE( //声明创建一个新的面板对象,自定义方式可参考mySelf.myDiagram.nodeTemplate
            go.Panel, //表明需要创建一个panel面板对象
            "Auto", //页面布局为自动
            MAKE( //声明构建一个圆角矩形
              go.Shape,
              "RoundedRectangle", {
                fill: "#44CCFF",
                stroke: null,
                width: 120
              },
              new go.Binding("figure", "figure") //声明并创建一个新的图形
            ),
            MAKE( //声明一个可编辑文本域
              go.TextBlock, {
                font: "12pt Helvetica, Arial, sans-serif",
                stroke: lightText,
                maxSize: new go.Size(160, NaN),
                //wrap: go.TextBlock.WrapFit, //文本域换行
                editable: true, //是否可编辑
                margin: 8,
                alignment: go.Spot.Center,
                wrap: go.TextBlock.WrapFit,
              },
              new go.Binding("text").makeTwoWay()
            )
          ),
          // four named ports, one on each side:
          makePort("T", go.Spot.Top, false, true),
          makePort("L", go.Spot.Left, true, true),
          makePort("R", go.Spot.Right, true, true),
          makePort("B", go.Spot.Bottom, true, false)
        )
      );
      mySelf.myDiagram.nodeTemplateMap.add(
        "Start",
        MAKE(
          go.Node,
          "Spot",
          nodeStyle(),
          MAKE( //声明创建一个新的面板对象,自定义方式可参考mySelf.myDiagram.nodeTemplate
            go.Panel, //表明需要创建一个panel面板对象
            "Auto", //页面布局为自动
            MAKE( //声明构建一个圆角矩形
              go.Shape,
              "Circle", {
                fill: "#79C900",
                stroke: null
              },
              new go.Binding("figure", "figure") //声明并创建一个新的图形
            ),
            MAKE( //声明一个可编辑文本域
              go.TextBlock, {
                font: "12pt Helvetica, Arial, sans-serif",
                stroke: lightText,
                maxSize: new go.Size(160, NaN),
                //wrap: go.TextBlock.WrapFit, //文本域换行
                editable: true, //是否可编辑
                    click: function(e, node) {

                        mySelf.myDiagram.model.setDataProperty(node, "text", "abby");
                    },
                margin: 8,
                alignment: go.Spot.Center,
                wrap: go.TextBlock.WrapFit,
              },
              new go.Binding("text").makeTwoWay()
            )
          ),
          // four named ports, one on each side:
          makePort("T", go.Spot.Top, false, true),
          makePort("L", go.Spot.Left, true, true),
          makePort("R", go.Spot.Right, true, true),
          makePort("B", go.Spot.Bottom, true, false)
        )
      );
      mySelf.myDiagram.nodeTemplateMap.add(
        "End",
        MAKE(
          go.Node,
          "Spot",
          nodeStyle(),
          MAKE( //声明创建一个新的面板对象,自定义方式可参考mySelf.myDiagram.nodeTemplate
            go.Panel, //表明需要创建一个panel面板对象
            "Auto", //页面布局为自动
            MAKE( //声明构建一个圆角矩形
              go.Shape,
              "Circle", {
                fill: "#DC3C00",
                stroke: null
              },
              new go.Binding("figure", "figure") //声明并创建一个新的图形
            ),
            MAKE( //声明一个可编辑文本域
              go.TextBlock, {
                font: "12pt Helvetica, Arial, sans-serif",
                stroke: lightText,
                maxSize: new go.Size(160, NaN),
                //wrap: go.TextBlock.WrapFit, //文本域换行
                editable: true, //是否可编辑
                margin: 8,
                alignment: go.Spot.Center,
                wrap: go.TextBlock.WrapFit,
              },
              new go.Binding("text").makeTwoWay()
            )
          ),
          // four named ports, one on each side:
          makePort("T", go.Spot.Top, false, true),
          makePort("L", go.Spot.Left, true, true),
          makePort("R", go.Spot.Right, true, true),
          makePort("B", go.Spot.Bottom, true, false)
        )
      );

      function nodeStyle() {
        return [
          // The Node.location comes from the "loc" property of the node data,
          // converted by the Point.parse static method.
          // If the Node.location is changed, it updates the "loc" property of the node data,
          // converting back using the Point.stringify static method.
          new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify),
          {
            // the Node.location is at the center of each node
            locationSpot: go.Spot.Center,
            isShadowed: true,
            shadowColor: "#888",
            // handle mouse enter/leave events to show/hide the ports
            mouseEnter: function (e, obj) {
              showPorts(obj.part, true);
            },
            mouseLeave: function (e, obj) {
              showPorts(obj.part, false);
            }
          }
        ];
      }

      function showPorts(node, show) {
        var diagram = node.diagram;
        if (!diagram || diagram.isReadOnly || !diagram.allowLink) return;
        node.ports.each(function (port) {
          port.stroke = (show ? "white" : null);
        });
      }

      //Node连接线
      function makePort(name, spot, output, input) {
        return MAKE(go.Shape, "Circle", {
          fill: "transparent",
          stroke: null, // this is changed to "white" in the showPorts function
          desiredSize: new go.Size(8, 8),
          alignment: spot,
          alignmentFocus: spot, // align the port on the main Shape
          portId: name, // declare this object to be a "port"
          fromSpot: spot,
          toSpot: spot, // declare where links may connect at this port
          fromLinkable: output,
          toLinkable: input, // declare whether the user may draw links to/from here
          cursor: "pointer" // show a different cursor to indicate potential link point
        });
      };
      mySelf.myDiagram.model = myModel;
      setTimeout(()=>{
          mySelf.init();
      },1000)

    },
    methods: {
        changeAttr(e){
            let node = this.myDiagram.model.findNodeDataForKey(this.activeNode.key);
            let key = Object.keys(e)[0];
            console.log(key)
            this.myDiagram.model.setDataProperty( node, key, e[key]);
            console.log(node)
      },
      moveLeft(){
          this.myDiagram.model.nodeDataArray.splice(0,1);
          this.myDiagram.model.updateTargetBindings(this.myDiagram.model.nodeDataArray);
          console.log(this.myDiagram.model.nodeDataArray);
      },
      moveRight(){

      },
      preventContextMenu(e){
          e.preventDefault();
      },
      leave(){
          this.showMenu = false;
      },
      resize(){

      },
    onSubmit() {
          console.log(this.myDiagram.model.toJson())
      localStorage.setItem('model',JSON.stringify(this.myDiagram.model.toJson()));
    },
      addLane(){  //添加泳道
          //{"key": 3, "isGroup": true, "text": "Group A"},
        console.log(this.createRandomId());
        let key = this.createRandomId();
          var CreateNode={
              key:this.createRandomId(), //设置key的方法，每个节点最好是有自己独立的key
              "loc":"",
              "isGroup": true,
              "text":"group",//也阔以是动态的值
           };
          let nodeData = this.myDiagram.model.nodeDataArray;
          console.log(nodeData)
          let lastGroupKey = '';
          for(let i=0;i<nodeData.length;i++){
              if(nodeData[i].isGroup){
                  lastGroupKey = nodeData[i].key;
              }
          }
          this.myDiagram.model.addNodeData(CreateNode);
          this.addLink(lastGroupKey,key);
      },
      createRandomId(){  //动态生成节点key
        return (new Date().getTime()).toString();
      },
      addLink(from,to){
          this.myDiagram.model.addLinkData({"from":from, "to":to});
      },
    init() {
      var mySelf = this;
      for(let i=0;i<this.componentList.length;i++){
          window.myPalette = MAKE(
              go.Palette,
              this.componentList[i]['id'], // must name or refer to the DIV HTML element
              {
                  scrollsPageOnFocus: false,
                  "animationManager.duration": 800, // slightly longer than default (600ms) animation
                  nodeTemplateMap: mySelf.myDiagram.nodeTemplateMap, // share the templates used by myDiagram
                  model: new go.GraphLinksModel(this.componentList[i]['children'])
              }
          );
      }
      /*window.myPalette = MAKE(
        go.Palette,
        "chart-palette", // must name or refer to the DIV HTML element
        {
          scrollsPageOnFocus: false,
          "animationManager.duration": 800, // slightly longer than default (600ms) animation
          nodeTemplateMap: mySelf.myDiagram.nodeTemplateMap, // share the templates used by myDiagram
          model: new go.GraphLinksModel([
            // specify the contents of the Palette
            {
              category: "Start",
              text: "Start"
            },
            {
              text: "Step"
            },
            {
              text: "main",
              figure: "Diamond"
            },
            {
              category: "End",
              text: "End"
            }
          ])
        }
      );*/
          /*window.myPalette = MAKE(
              go.Palette,
              "chart-palette2", // must name or refer to the DIV HTML element
              {
                  scrollsPageOnFocus: false,
                  "animationManager.duration": 800, // slightly longer than default (600ms) animation
                  nodeTemplateMap: mySelf.myDiagram.nodeTemplateMap, // share the templates used by myDiagram
                  model: new go.GraphLinksModel([
                      // specify the contents of the Palette
                      {
                          category: "Start",
                          text: "one"
                      },
                      {
                          text: "two"
                      },
                      {
                          text: "three",
                          figure: "Diamond"
                      },
                      {
                          category: "End",
                          text: "four"
                      }
                  ])
              }
          );*/
      },
    }
  }
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style lang="less" scoped>
  .el-collapse-item__header{
    white-space: nowrap;
    overflow: hidden;
  }
  .e-flex{
    display: flex;
    align-items: center;
  }
  .btn_group{
    padding: 4px 10px;
    justify-content: space-between;
    .btn{
      padding: 6px 10px;
    }
  }
  #form-wrap {
    padding: 20px 40px;
    // background-color: white;
    border: solid 1px rgb(244, 244, 244);
  }

  #submit {
    width: 102px;
    height: 40px;
    float: right;
    margin: 20px 5px 16px 0;
  }
  .split_pane{
    border-left: 6px solid #dce3e8;
    position: relative;
    background: #ffffff;
    .collapse{
      height: calc(100% - 34px);overflow-y: auto;margin-bottom: 120px;padding-left: 10px;
    }
  }
  .chart-palette-box{
    width: 100%;
    height: 100%;
    //border-bottom: 1px solid #ececec;
    //overflow-y: scroll;
    display: flex;
    justify-content: center;
  }
  .chart-palettes {
    width: 180px;
    height: 100%;
   // margin-right: 30px;
    background-color: white;
  }
  #wrap{
    position: relative;
    .contextMenu{
      position: absolute;
      z-index: 9999;
      background: #ffffff;
      width: 90px;
      padding: 0 10px;
      border-radius: 4px;
      border: 1px solid #ececec;
      box-shadow: 0px 2px 6px 0px #aaaaaa;
      .option{
        height: 45px;
        line-height: 45px;
      }
      .line{
        border-bottom: 1px solid #ececec;
      }
    }
  }

  #chart-wrap {
    width: 100%;
    display: flex;
    justify-content: space-between;
    margin-bottom: 22px;



    #chart-diagram {
      flex-grow: 1;
      height: 720px;
      background-color: white;
      border: solid 1px rgb(244, 244, 244);
    }
  }

  #lateEntry {
    clear: both;
    background-color: rgb(255, 255, 255);
    border: solid 1px rgb(244, 244, 244);

    > span {
      display: inline-block;
      height: 50px;
      font-size: 16px;
      line-height: 50px;
      text-indent: 30px;
      letter-spacing: 0.8px;
      text-align: left;
      color: rgb(35, 35, 35);
      // border-bottom: 1px solid rgb(234, 234, 234);
    }
  }
</style>
